using GameServer.ShootingGame.RenderableClasses;
using GameServer;
using GameServer.Common.Utils;
using System.Collections.Generic;
using System.Drawing;
using System;
using GameServer.ShootingGame.WeaponsClasses.LaunchProfiles;
namespace GameServer.ShootingGame.WeaponsClasses
{

    public class Weapon : AttachableObject
    {
        public int type;
        private WeaponInfo weaponInfo_Primary;
        private WeaponInfo weaponInfo_Secondary;
        public bool isMouseAimAdjustEnabled;
        public double damageModifier;
        public double coolDownModifier;
        public bool isAmmoShared;
        private bool isTriggerDepressed;
        private int timeTriggerDepressed;
        private double nozzle_OriginalRelativePointX;
        private double nozzle_OriginalRelativePointY;
        private PointF nozzlePoint;

        public Weapon()
        {
            this.weaponInfo_Primary = null;
            this.weaponInfo_Secondary = null;
            this.isAmmoShared = false;
            isMouseAimAdjustEnabled = false;
            damageModifier = 1;
            coolDownModifier = 1;
            nozzlePoint = PointF.Empty;
            type = 0;
        }


        override public void Update()
        {
            if (isMouseAimAdjustEnabled)
                MouseAim();
            if (isTriggerDepressed)
                timeTriggerDepressed += 1;
            else
                timeTriggerDepressed = 0;
            base.Update();
            weaponInfo_Primary.CoolDownTimeCount -= Convert.ToInt16(coolDownModifier);

        }

        public void MouseAim()
        {
            if (AttachedTo is PlayerObject)
            {
                //facing = Math2.GetAngleOfElevationDegree(localToGlobal(preferredCentre).x, localToGlobal(preferredCentre).y, GamePlayManager.instance.mouseX, GamePlayManager.instance.mouseY);
                Facing = AttachedTo.Facing;
            }
            //			var m:Matrix = new Matrix();
            //			MatrixTransformer.rotateAroundInternalPointF(m, model.body.width/2.0, model.body.height/2.0, facing);
            //			model.transform.matrix = m;
        }

        //Returns array of launched ordinance
        public List<Ordinance> Fire_Primary(double targetX, double targetY)
        {
            List<Ordinance> fireArray = null;
            PointF globalPoint = new PointF(CollidablePart.X, CollidablePart.Y);

            double distance = Math.Sqrt(Math.Pow(targetX - globalPoint.X, 2) + Math.Pow(targetY - globalPoint.Y, 2));

            if (weaponInfo_Primary.CoolDownTimeCount <= 0)
            {
                if (weaponInfo_Primary.Accuracy < 1)
                {

                    targetX += distance * Math2.RandDouble(GamePlayManager.random, (weaponInfo_Primary.Accuracy - 1) / 2.0, (1 - weaponInfo_Primary.Accuracy) / 2.0);
                    targetY += distance * Math2.RandDouble(GamePlayManager.random, (weaponInfo_Primary.Accuracy - 1) / 2.0, (1 - weaponInfo_Primary.Accuracy) / 2.0);
                }
                fireArray = LaunchProfile.Launch(weaponInfo_Primary.launchprofile, this, weaponInfo_Primary, targetX, targetY);
                if (fireArray != null)
                    weaponInfo_Primary.CoolDownTimeCount = weaponInfo_Primary.coolDownTime;
            }
            return fireArray;
        }

        public List<Ordinance> Fire_Secondary(double targetX, double targetY)
        {
            if (weaponInfo_Secondary != null)
                return LaunchProfile.Launch(weaponInfo_Secondary.launchprofile, this, weaponInfo_Secondary, targetX, targetY);
            else
                return null;
        }
        
        public PointF NozzlePoint
        {
            get
            {
                if (nozzlePoint == PointF.Empty)
                {
                    nozzlePoint = new PointF(Convert.ToSingle(xPosition + Math.Cos(nozzle_OriginalRelativePointX)), Convert.ToSingle(yPosition + Math.Sin(nozzle_OriginalRelativePointY)));
                    return nozzlePoint;
                }
                else
                {
                    nozzlePoint.X = Convert.ToSingle(xPosition + Math.Cos(nozzle_OriginalRelativePointX));
                    nozzlePoint.Y = Convert.ToSingle(yPosition + Math.Sin(nozzle_OriginalRelativePointY));
                }
                return nozzlePoint;
            }
            set { nozzlePoint = value; }
        }

        public WeaponInfo WeaponInfo_Primary
        {
            get
            {
                return weaponInfo_Primary;
            }
            set
            {
                weaponInfo_Primary = value;
            }
        }
        public WeaponInfo WeaponInfo_Secondary
        {
            get
            {
                return weaponInfo_Secondary;
            }
            set
            {
                weaponInfo_Secondary = value;
            }
        }

        public int TimeTriggerDepressed
        {
            get
            {
                return timeTriggerDepressed;
            }
        }

        public bool IsAmmoShared
        {
            get
            {
                return isAmmoShared;
            }
        }

        public override GameObject AttachedTo
        {
            get
            {
                return base.AttachedTo;
            }
            set
            {
                base.AttachedTo = value;
                weaponInfo_Primary.ordinanceSample.owner = AttachedTo;
                //weaponInfo_Secondary.ordinanceSample.owner = attachedTo;
            }
        }

        public bool IsTriggerDepressed
        {
            get { return isTriggerDepressed; }
            set { isTriggerDepressed = value; }
        }
    }
}